#include "FMedia.h"

FMedia::FMedia() {
    pthread_mutex_init(&p_mutex, NULL);
    pthread_cond_init(&p_cond, NULL);
    this->clock = 0;
}

int FMedia::push(AVPacket *packet) {
    pthread_mutex_lock(&p_mutex);
    AVPacket *dst = (AVPacket *) av_mallocz(sizeof(AVPacket));
    av_packet_ref(dst, packet);
    p_queue.push(dst);
    pthread_cond_signal(&p_cond);
    pthread_mutex_unlock(&p_mutex);
    return 0;
}

int FMedia::pop(AVPacket *packet) {
    pthread_mutex_lock(&p_mutex);
    while (isPlaying) {
        if (!p_queue.empty()) {
            AVPacket *src = p_queue.front();
            if (av_packet_ref(packet, src)) {
                break;
            }
            p_queue.pop();
            av_free(src);
            break;
        } else {
            pthread_cond_wait(&p_cond, &p_mutex);
        }
    }
    pthread_mutex_unlock(&p_mutex);
    return 0;
}

void FMedia::stop() {
    // 有可能在等待数据，pop 函数阻塞，这里需要加锁
    pthread_mutex_lock(&p_mutex);
    isPlaying = 0;
    pthread_cond_signal(&p_cond);
    pthread_mutex_unlock(&p_mutex);
    pthread_join(p_tid, 0);
}

void FMedia::release() {
    stop();
    pthread_mutex_lock(&p_mutex);
    // 释放未播放的数据
    int i = 0;
    for (; i < p_queue.size(); i++) {
        AVPacket *packet = p_queue.front();
        p_queue.pop();
        av_free(packet);
    }
    pthread_mutex_unlock(&p_mutex);
    avcodec_close(codec_ctx);
    av_free(out_buf);
}

FMedia::~FMedia() {
    pthread_mutex_destroy(&p_mutex);
    pthread_cond_destroy(&p_cond);
}

